import logging
from celery import shared_task
from django.utils import timezone

from django.db import transaction
from .models import ExamRoom, ExamRegistration, ExamPaper, ExamNotification

logger = logging.getLogger(__name__)

@shared_task
def prepare_exam_room(exam_room_id):
    """考试开始前10秒为考生出题。并通知考生准备进入考场"""
    logger.info(f"准备考场 {exam_room_id} 的考试...")
    print('exam_room_id', exam_room_id)
    print('准备出题了……')
    try:
        exam_room = ExamRoom.objects.get(id=exam_room_id)
        if exam_room.status == 'preparing':
            # 检查是否已生成试卷
            papers_count = ExamPaper.objects.filter(exam_room=exam_room).count()

            if papers_count == 0:
                # 如果还没有生成试卷，立即生成
                registrations = ExamRegistration.objects.filter(
                    exam_room=exam_room,
                    status='registered'
                )
                for registration in registrations:
                    ExamPaper.generate_paper(exam_room, registration.examinee)
                papers_count = registrations.count()
                print(f'出题完成，出题数量：{papers_count}')

        if exam_room.status == 'preparing':
            # 向所有考生发送考试开始通知
            registrations = ExamRegistration.objects.filter(
                exam_room=exam_room,
                status='registered'
            )

            for registration in registrations:
                ExamNotification.objects.create(
                    exam_room=exam_room,
                    examinee=registration.examinee,
                    notification_type='system',
                    title=f"考试 {exam_room.name} 即将开始",
                    content=f"""
尊敬的考生：

您报名参加的考试 "{exam_room.name}" 即将开始。

- 考试时长: {exam_room.duration} 分钟
- 考试总分: {exam_room.total_score} 分
- 结束时间: {exam_room.end_time.strftime('%Y-%m-%d %H:%M')}

请准备进入考场参加考试。祝您考试顺利！
"""
                )

            return f"考场 {exam_room.name} 即将开始，共有 {papers_count} 名考生参加考试"
    except ExamRoom.DoesNotExist:
        return f"考场ID {exam_room_id} 不存在"

@shared_task
def test_simple_task(x=10):
    """
    一个简单的测试任务，用于验证Celery的基本功能
    不依赖任何模型或复杂逻辑
    """
    import time
    time.sleep(2)  # 模拟一些工作
    result = x * x
    logger.info(f"测试任务执行完成：{x} * {x} = {result}")
    return result

@shared_task
def start_exam_room(exam_room_id):
    """考试开始时更新考场状态并通知考生"""
    logger.info(f"开始考场 {exam_room_id} 的考试...")
    try:
        exam_room = ExamRoom.objects.get(id=exam_room_id)
        if exam_room.status == 'preparing':
            # 检查是否已生成试卷
            papers_count = ExamPaper.objects.filter(exam_room=exam_room).count()

            if papers_count == 0:
                # 如果还没有生成试卷，立即生成
                registrations = ExamRegistration.objects.filter(
                    exam_room=exam_room,
                    status='registered'
                )
                for registration in registrations:
                    ExamPaper.generate_paper(exam_room, registration.examinee)
                papers_count = registrations.count()

            # 使用事务确保状态更新的一致性
            with transaction.atomic():
                # 更新考场状态为进行中
                exam_room.status = 'in_progress'
                exam_room.save_status()

            # 向所有考生发送考试开始通知
            registrations = ExamRegistration.objects.filter(
                exam_room=exam_room,
                status='registered'
            )

            for registration in registrations:
                ExamNotification.objects.create(
                    exam_room=exam_room,
                    examinee=registration.examinee,
                    notification_type='system',
                    title=f"考试 {exam_room.name} 已开始",
                    content=f"""
尊敬的考生：

您报名参加的考试 "{exam_room.name}" 已经开始。

- 考试时长: {exam_room.duration} 分钟
- 考试总分: {exam_room.total_score} 分
- 结束时间: {exam_room.end_time.strftime('%Y-%m-%d %H:%M')}

请立即进入考场参加考试。祝您考试顺利！
"""
                )

            return f"考场 {exam_room.name} 已开始，共有 {papers_count} 名考生参加考试"
    except ExamRoom.DoesNotExist:
        return f"考场ID {exam_room_id} 不存在"
    except Exception as e:
        logger.error(f"开始考试时发生错误: {str(e)}")
        return f"开始考试时发生错误: {str(e)}"

@shared_task
def finish_exam_room(exam_room_id):
    """考试结束时的处理：强制交卷、计算分数、更新状态、发送通知"""
    logger.info(f"结束考场 {exam_room_id} 的考试...")
    try:
        exam_room = ExamRoom.objects.get(id=exam_room_id)
        if exam_room.status == 'in_progress':
            # 获取所有未提交的试卷
            unsubmitted_papers = ExamPaper.objects.filter(
                exam_room=exam_room,
                is_submitted=False
            )

            # 强制提交所有未提交的试卷
            for paper in unsubmitted_papers:
                paper.is_submitted = True
                paper.submitted_at = timezone.now()
                paper.save()

            # 计算考试统计数据
            all_papers = ExamPaper.objects.filter(exam_room=exam_room)
            total_papers = all_papers.count()
            if total_papers > 0:
                total_scores = sum(float(paper.total_score or 0) for paper in all_papers)
                exam_room.average_score = round(total_scores / total_papers, 2)
            else:
                exam_room.average_score = 0

            # 使用事务确保状态更新的一致性
            with transaction.atomic():
                # 更新考场状态为已结束
                exam_room.status = 'finished'
                exam_room.save_status()

            # 更新考生报名状态为已完成
            ExamRegistration.objects.filter(
                exam_room=exam_room,
                status='registered'
            ).update(status='completed')

            # 向所有考生发送考试结束通知
            registrations = ExamRegistration.objects.filter(
                exam_room=exam_room,
                status='completed'
            )

            for registration in registrations:
                # 获取考生的试卷
                try:
                    paper = ExamPaper.objects.get(
                        exam_room=exam_room,
                        examinee=registration.examinee
                    )
                    score = paper.total_score
                except ExamPaper.DoesNotExist:
                    score = 0

                ExamNotification.objects.create(
                    exam_room=exam_room,
                    examinee=registration.examinee,
                    notification_type='system',
                    title=f"考试 {exam_room.name} 已结束",
                    content=f"""
尊敬的考生：

您参加的考试 "{exam_room.name}" 已结束。

您的考试成绩如下：
- 个人得分：{score} 分
- 考试平均分：{exam_room.average_score:.2f} 分
- 考试总分：{exam_room.total_score} 分

请在个人中心查看详细的答题情况，以便了解自己的薄弱环节。

祝您进步！
"""
                )

            return f"考场 {exam_room.name} 已结束，平均分：{exam_room.average_score:.2f}，参考人数：{total_papers}"
    except ExamRoom.DoesNotExist:
        return f"考场ID {exam_room_id} 不存在"
